#define _GNU_SOURCE
#include "app_mqtt.h"
#include "log/log.h"
#include <MQTTClient.h>
#include <unistd.h>

static MQTTClient_message pubmsg = MQTTClient_message_initializer;
static MQTTClient client;
static MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
static int (*recv_callback)(char *, int);

static void delivered(void *context, MQTTClient_deliveryToken dt)
{
    log_debug("消息发送完成");
}
// 收到消息的回调函数
static int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
    int result = 0; // 定义一个代表消息未正确处理的值
    // 调用recv_callback函数
    if (recv_callback)
    {
        result = recv_callback(message->payload, message->payloadlen) == 0 ? 1 : 0;
    }
    MQTTClient_freeMessage(&message);
    MQTTClient_free(topicName);
    return result; // 表示消息处理完成,0表示未处理完成
}
// 连接断开的d回调函数
static void connlost(void *context, char *cause)
{
    printf("\nConnection lost\n");
    printf("     cause: %s\n", cause);
    log_error("连接断开，原因：%s", cause);
}

int app_mqtt_init(void)
{

    int result;

    // 1.创建客户端

    if (result = MQTTClient_create(&client, ADDRESS, "client_id", MQTTCLIENT_PERSISTENCE_NONE, NULL) != MQTTCLIENT_SUCCESS)
    {
        log_error("MQTTClient_create failed, result = %d", result);
        return -1;
    }

    // 2.设置回调函数
    if (result = MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered) != MQTTCLIENT_SUCCESS)
    {
        log_error("MQTTClinent_setCallbacks failed, result = %d", result);
        MQTTClient_destroy(&client);
        return -1;
    }

    // 3.连接服务器
    if (result = MQTTClient_connect(client, &conn_opts) != MQTTCLIENT_SUCCESS)
    {
        log_error("MQTTClient_connect failed, result = %d", result);
        MQTTClient_destroy(&client);
        return -1;
    }

    // 4.订阅主题
    if (result = MQTTClient_subscribe(client, TOPIC_PULL, QOS) != MQTTCLIENT_SUCCESS)
    {
        log_error("MQTTClient_subscribe failed, result = %d", result);
        app_mqtt_close();
        return -1;
    }
    return 0;
}

int app_mqtt_send(char *data, int len)
{
    // 设置消息内容
    pubmsg.payload = data;
    pubmsg.payloadlen = len;
    pubmsg.qos = QOS;
    if (MQTTClient_publishMessage(client, TOPIC_PUSH, &pubmsg, NULL) != MQTTCLIENT_SUCCESS)
    {
        log_error("MQTTClient_publishMessage failed");
        return -1;
    }

    return 0;
}

void app_mqtt_registRecvCallback(int (*callback)(char *, int))
{
    recv_callback = callback;
}

void app_mqtt_close(void)
{
    MQTTClient_disconnect(client, TIMEOUT);
    MQTTClient_destroy(&client);
}
